package com.example.easyexcel.exports.customized.strategy;

import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description 自适应列宽
 * https://blog.csdn.net/weixin_37530941/article/details/127272417
 * https://www.cnblogs.com/zxg-blog/p/16486879.html
 * @ClassName AutoHeadColumnWidthStyleStrategy
 * @date 2022.10.11 17:50
 */
public class AutoHeadColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy  {
    // 保底宽度
    private static final Integer COLUMN_WIDTH = 10;
    // 最大宽度
    private static final Integer MAX_COLUMN_WIDTH = 50;
    private Map<Integer, Map<Integer, Integer>> CACHE = new HashMap(8);
    public AutoHeadColumnWidthStyleStrategy() {}

    @Override
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell,
                                  Head head, Integer relativeRowIndex, Boolean isHead) {
         if ( isHead || cell.getRowIndex() == 1 ) {
            Map<Integer, Integer> maxColumnWidthMap = CACHE.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>());
            // 计算列宽
            Integer columnWidth = dataLength(cellDataList,cell,isHead);
            // 限制列宽
//            if (columnWidth >= 0) {
                if (columnWidth > MAX_COLUMN_WIDTH) {
                    columnWidth = MAX_COLUMN_WIDTH;
                } else if (columnWidth < COLUMN_WIDTH) {
                    columnWidth = COLUMN_WIDTH ;
                }
                Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());
                if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
                    maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
                    writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256 );
                }
//            }
        }
    }


    private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
        if (isHead) {
            String cellValue = cell.getStringCellValue() ;
            int length = cellValue.getBytes().length ; // 列宽依据头行的字符数
            for (char c : cellValue.toCharArray()) {
                // 头行中 存在中文的 宽度要扩一下
                if( !String.valueOf(c).matches("[\u4e00-\u9fa5]") ){ // https://blog.csdn.net/SoWhatWorld/article/details/104992259
                    length++;
                }
            }
            return length ;
        }else if(cell.getRowIndex() == 1){
            WriteCellData<?> cellData = cellDataList.get(0);
            CellDataTypeEnum type = cellData.getType();
            if (type != null) {
                switch (type) {
//                case STRING:
//                    return cellData.getStringValue().getBytes().length;
//                case BOOLEAN:
//                    return cellData.getBooleanValue().toString().getBytes().length;
//                case NUMBER:
//                    return cellData.getNumberValue().toString().getBytes().length;
                    case DATE:
                        // 只对第一个数据行中 是日期类型的 指定统一列宽
                        return "yyyy-MM-dd HH:mm:ss".length(); // cellData.getDateValue().toString().getBytes().length ;
                }
            }
        }
        return -1;
    }

}
